import bencode
import json
import random
import binascii
import os
import shutil
import hashlib
from tqdm import tqdm




# Total number of generated fastresume&torrent
TOTAL = 8000
# Maximum nesting level of generated directory
MINIMUM_NEST_DEPTH = 2
DIRECTORY_LEVEL = 6
FASTRESUME_TEMPLATE = './BT_backup/0b67efc7464644eba4b3b23f6198ffaffe639487.fastresume'
TORRENT_TEMPLATE = './BT_backup/The_Shawshank_Redemption_(1994)_[2160p]_[TorrentGalaxy.hair].torrent'



def gen_filename(filenames:list, total:int):
    index = 0
    cycle = 0
    link = ['&','@ ','  $ ','__',' ']

    random.shuffle(filenames)
    while total > 0:
        if index == len(filenames):
            index = 0
            cycle += 1
            random.shuffle(filenames)
        name = filenames[index]
        total -= 1
        index += 1
        for n in random.sample(filenames, cycle):
            if random.random() > .5:
                name = f"{name}{random.choice(link)}[{n}]"
            else:
                name = f"{name}{random.choice(link)}{n}"

        yield name


def gen_directory(roots:list, dirs:list, total:int):

    random.shuffle(roots)
    random.shuffle(dirs)

    # 每层目录选择隔离
    multi_level_dirs = []
    for i in range(DIRECTORY_LEVEL):
        multi_level_dirs.append(dirs[i::DIRECTORY_LEVEL])
    
    while total > 0:
        total -= 1
        dir_level = random.randint(MINIMUM_NEST_DEPTH, DIRECTORY_LEVEL)
        name = '/'.join([random.choice(x) for x in multi_level_dirs[:dir_level]])
        name = random.choice(roots) + name

        yield name

def generate_fastest_hex():
    # 生成20字节随机数据（每个字节对应2位十六进制）
    return os.urandom(20).hex().lower()

def test_once():
    """
    测试生成fastresume和torrent
    """
    with open(FASTRESUME_TEMPLATE, 'rb') as f:
        template_fastresume = bencode.decode(f.read())
    with open(TORRENT_TEMPLATE, 'rb') as f:
        template_torrent = bencode.decode(f.read())
    with open('./fake_name.json', 'rb') as f:
        json_content = json.load(f)

    # name list
    filenames = json_content['filename']
    dirs = json_content['directory']
    roots = json_content['root']

    # 生成器
    gen_dir = gen_directory(roots, dirs, 1)
    gen_file = gen_filename(filenames, 1)



    # ss = binascii.b2a_hex(template_fastresume['info-hash']).decode('latin-1')
    dir_path = next(gen_dir)
    filename = next(gen_file)
    hash = generate_fastest_hex()
    b_hash = binascii.a2b_hex(hash)
    byte_size = random.randint(4096, 1125899906842624) # [4kB, 1PB]

    # 生成fastresume文件
    template_fastresume['info-hash'] = b_hash
    template_fastresume['qBt-name'] = filename
    template_fastresume['qBt-savePath'] = dir_path
    template_fastresume['save_path'] = os.path.normpath(template_fastresume['qBt-savePath']) # windows path
    template_fastresume['total_downloaded'] = byte_size
    # 生成torrent文件（单文件格式）
    template_torrent['info']['name'] = filename
    template_torrent['info']['length'] = byte_size

    # 写入文件
    os.makedirs('./output/test_once', exist_ok=True)
    with open(f'./output/test_once/{hash}.fastresume', 'wb') as f:
        f.write(bencode.bencode(template_fastresume))
    with open(f'./output/test_once/{hash}.torrent', 'wb') as f:
        f.write(bencode.bencode(template_torrent))

    print('test once')

# def generate_torrent(info_hash, file_name, file_size, save_path):


def get_hash_info():
    """
    种子文件hash值获取
    """
    with open(TORRENT_TEMPLATE, 'rb') as f:
        template_fastresume = bencode.decode(f.read())

    info_dict = template_fastresume['info']
    info_bencoded = bencode.bencode(info_dict)
    info_hash_sha1 = hashlib.sha1(info_bencoded)
    info_hash = info_hash_sha1.hexdigest()
    info_bhash = info_hash_sha1.digest()

    print('hash',info_hash)


def genarate_multi():
    with open(FASTRESUME_TEMPLATE, 'rb') as f:
        template_fastresume = bencode.decode(f.read())
    with open(TORRENT_TEMPLATE, 'rb') as f:
        template_torrent = bencode.decode(f.read())
    with open('./fake_name.json', 'rb') as f:
        json_content = json.load(f)

    # name list
    filenames = json_content['filename']
    dirs = json_content['directory']
    roots = json_content['root']

    # 生成器
    gen_dir = gen_directory(roots, dirs, TOTAL)
    gen_file = gen_filename(filenames, TOTAL)

    if os.path.exists(f'./output/{TOTAL}'):
        shutil.rmtree(f'./output/{TOTAL}', True)
    os.makedirs(f'./output/{TOTAL}', exist_ok=True)


    for i in tqdm(range(TOTAL), 'genarate', TOTAL):
        # 主要属性
        dir_path = next(gen_dir)
        filename = next(gen_file)
        hash = generate_fastest_hex()
        b_hash = binascii.a2b_hex(hash)
        byte_size = random.randint(4096, 1125899906842624) # [4kB, 1PB]
        # 生成fastresume文件
        template_fastresume['info-hash'] = b_hash
        template_fastresume['qBt-name'] = filename
        template_fastresume['qBt-savePath'] = dir_path
        template_fastresume['save_path'] = os.path.normpath(template_fastresume['qBt-savePath']) # windows path
        template_fastresume['total_downloaded'] = byte_size
        # 生成torrent文件（单文件格式）
        template_torrent['info']['name'] = filename
        template_torrent['info']['length'] = byte_size

        # 保存
        with open(f'./output/{TOTAL}/{hash}.fastresume', 'wb') as f:
            f.write(bencode.bencode(template_fastresume))
        with open(f'./output/{TOTAL}/{hash}.torrent', 'wb') as f:
            f.write(bencode.bencode(template_torrent))

    


if __name__ == "__main__":
    # test_once()

    genarate_multi()


    # get_hash_info()
    print('done.')
